package com.atguigu.gulimall.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.common.to.SkuEsModel;
import com.atguigu.common.to.SkuReductionTo;
import com.atguigu.common.to.SpuBoundTo;
import com.atguigu.common.utils.Query;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.entity.*;
import com.atguigu.gulimall.product.feign.CouponFeignService;
import com.atguigu.gulimall.product.feign.SearchFeignService;
import com.atguigu.gulimall.product.feign.WareFeignService;
import com.atguigu.gulimall.product.service.*;
import com.atguigu.gulimall.product.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;

import com.atguigu.gulimall.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private AttrService attrService;
    @Autowired
    private SpuInfoService spuInfoService;

    @Autowired
    private SpuInfoDescService spuInfoDescService;

    @Autowired
    private SpuImagesService spuImagesService;

    @Autowired
    private SkuImagesService skuImagesService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SearchFeignService searchFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }


    @Override
    @Transactional
    public void saveSpuInfo(SpuSaveVo spuSaveVo) {
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(spuSaveVo, spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        spuInfoService.saveBaseSpuInfo(spuInfoEntity);
        //保存spu的描述图片
        List<String> decript = spuSaveVo.getDecript();
        SpuInfoDescEntity descEntity = new SpuInfoDescEntity();
        descEntity.setSpuId(spuInfoEntity.getId());
        if (decript != null) {
            descEntity.setDecript(String.join(",", decript));
        }
        spuInfoDescService.saveSpuInfoDesc(descEntity);
        //保存Spu的图片集
        List<String> images = spuSaveVo.getImages();
        spuImagesService.saveSpuInfoImages(spuInfoEntity.getId(), images);
        //保存spu的规格参数
        List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
        List<ProductAttrValueEntity> collect = baseAttrs.stream().map(s -> {
            ProductAttrValueEntity valueEntity = new ProductAttrValueEntity();
            valueEntity.setSpuId(spuInfoEntity.getId());
            valueEntity.setAttrId(s.getAttrId());
            AttrEntity id = attrService.getById(s.getAttrId());
            valueEntity.setAttrName(id.getAttrName());
            valueEntity.setAttrValue(s.getAttrValues());
            return valueEntity;
        }).collect(Collectors.toList());
        productAttrValueService.saveProductAttr(collect);
        //保存Spu的积分信息
        Bounds bounds = spuSaveVo.getBounds();
        SpuBoundTo spuBoundTo = new SpuBoundTo();
        BeanUtils.copyProperties(bounds, spuBoundTo);
        spuBoundTo.setSpuId(spuInfoEntity.getId());
        R r = couponFeignService.saveSpuBounds(spuBoundTo);
        if (r.getCode() != 0) {
            log.error("远程保存spu积分信息失败");
        }


        //保存spu对应所有sku消息
        List<Skus> skus = spuSaveVo.getSkus();
        if (skus != null && skus.size() > 0) {
            skus.forEach(entity -> {
                String defaultImg = "";
                for (Images image : entity.getImages()) {
                    if (image.getDefaultImg() == 1) {
                        defaultImg = image.getImgUrl();
                    }
                }
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(entity, skuInfoEntity);
                skuInfoEntity.setSpuId(spuInfoEntity.getId());
                skuInfoEntity.setBrandId(skuInfoEntity.getBrandId());
                skuInfoEntity.setCatalogId(skuInfoEntity.getCatalogId());
                skuInfoEntity.setSaleCount(0L);
                skuInfoEntity.setSkuDefaultImg(defaultImg);
                skuInfoService.save(skuInfoEntity);
                Long skuId = skuInfoEntity.getSkuId();

                List<SkuImagesEntity> imagesEntities = entity.getImages().stream().filter(s -> {
                    return StringUtils.isNotEmpty(s.getImgUrl());
                }).map(s -> {
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                    skuImagesEntity.setSkuId(skuId);
                    skuImagesEntity.setDefaultImg(s.getDefaultImg());
                    skuImagesEntity.setImgUrl(s.getImgUrl());
                    return skuImagesEntity;
                }).collect(Collectors.toList());
                skuImagesService.saveBatch(imagesEntities);

                //sku对应的销售属性
                List<Attr> attr = entity.getAttr();
                List<SkuSaleAttrValueEntity> attrValueEntities = attr.stream().map(s -> {
                    SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(s, skuSaleAttrValueEntity);
                    skuSaleAttrValueEntity.setSkuId(skuId);
                    return skuSaleAttrValueEntity;
                }).collect(Collectors.toList());
                skuSaleAttrValueService.saveBatch(attrValueEntities);
                //sku优惠价、满减等信息
                SkuReductionTo skuReductionTo = new SkuReductionTo();
                BeanUtils.copyProperties(entity, skuReductionTo);
                if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(BigDecimal.ZERO) == 1 ||
                        CollectionUtil.isNotEmpty(skuReductionTo.getMemberPrice())) {
                    R r1 = couponFeignService.saveSkuReduction(skuReductionTo);
                    if (r1.getCode() != 0) {
                        log.error("远程保存sku信息失败");
                    }
                }

            });


        }

    }

    @Override
    public void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
        this.baseMapper.insert(spuInfoEntity);

    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> qw = new QueryWrapper<>();
        String key = params.get("key").toString();
        if (StringUtils.isNotEmpty(key)){
       qw.and(s->{s.lambda()
               .eq(SpuInfoEntity::getId,params.get("key"))
               .or()
               .like(SpuInfoEntity::getSpuName,params.get("key"));});
        }
        String status = params.get("status").toString();
        if (StringUtils.isNotEmpty(status)){
               qw.lambda().eq(SpuInfoEntity::getPublishStatus,status);
        }
        String brandId = params.get("brandId").toString();
        if (StringUtils.isNotEmpty(brandId)&&!brandId.equals("0")){

            qw.lambda().eq(SpuInfoEntity::getBrandId,brandId);
        }
        String catelogId = params.get("catelogId").toString();
        if (StringUtils.isNotEmpty(catelogId)&&!catelogId.equals("0")){
            qw.lambda().eq(SpuInfoEntity::getCatalogId,catelogId);

        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),qw
        );

        return new PageUtils(page);
    }

    @Autowired
    private WareFeignService wareFeignService;

    @Override
    public String upSpu(Long spuId) {
        //1.获取spu对应sku、以及sku库存信息
        List<SkuInfoEntity> list = skuInfoService.list(new LambdaQueryWrapper<SkuInfoEntity>().eq(SkuInfoEntity::getSpuId,spuId));
        if (CollectionUtil.isNotEmpty(list)) {
           //TODO 获取库存准备
            Map<Long, Boolean> skuHasStockMap= null;
            try {
                List<Long> skuIds = list.stream().map(s -> s.getSkuId()).collect(Collectors.toList());
                List<SkuHasStockVo> skuHasStockVos = wareFeignService.skuIdsHasStock(skuIds);

                if (CollectionUtil.isNotEmpty(skuHasStockVos)){
                   skuHasStockMap = skuHasStockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
                }
            } catch (Exception e) {
                log.error("库存查询服务异常,异常原因：{}",e);
            }
            //4.因为sku的规格属性都是继承SPU的，所以根据spuid查询出当前sku所有可以被检索的规格属性
            List<ProductAttrValueEntity> attrValueEntities = productAttrValueService.baseAttrlistforspu(spuId);
            List<SkuEsModel.Attrs> attrs = attrValueEntities.stream().map(s -> {
                AttrEntity attrEntity = attrService.getById(s.getAttrId());
                if (attrEntity.getSearchType() != 1) {
                    return null;
                }
                SkuEsModel.Attrs skuAttr = new SkuEsModel.Attrs();
                BeanUtils.copyProperties(s, skuAttr);
                return skuAttr;
            }).collect(Collectors.toList());


            Map<Long, Boolean> finalSkuHasStockMap1 = skuHasStockMap;
            List<SkuEsModel> skuEsModels = list.stream().map(entity -> {
                //封装基本信息
                SkuEsModel skuEsModel = new SkuEsModel();
                BeanUtils.copyProperties(entity, skuEsModel);
                skuEsModel.setSkuPrice(entity.getPrice());
                skuEsModel.setSkuImg(entity.getSkuDefaultImg());
                //TODO 查询库存
               if (finalSkuHasStockMap1 !=null&&finalSkuHasStockMap1.containsKey(entity.getSkuId())){
                skuEsModel.setHasStock(finalSkuHasStockMap1.get(entity.getSkuId()));
               }else {
                   skuEsModel.setHasStock(true);
               }
               //2.热度评分
                skuEsModel.setHotScore(0L);
                //3.设置品牌与分类相关信息
                BrandEntity brandEntity = brandService.getById(entity.getBrandId());
                if (brandEntity!=null){
                    skuEsModel.setBrandName(brandEntity.getName());
                    skuEsModel.setBrandImg(brandEntity.getLogo());
                }
                CategoryEntity categoryEntity = categoryService.getById(entity.getCatalogId());
                if (categoryEntity!=null){
                    skuEsModel.setCatalogName(categoryEntity.getName());
                }
                //4.设置attr
                skuEsModel.setAttrs(attrs);
                return skuEsModel;
            }).collect(Collectors.toList());

            //调用search服务进行保存
            R r = searchFeignService.productUp(skuEsModels);

            if (r.getCode()==0){
                //修改商品状态
                LambdaQueryWrapper<SpuInfoEntity> qw = new LambdaQueryWrapper<>();
                qw.eq(SpuInfoEntity::getId,spuId);
                SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
                spuInfoEntity.setId(spuId);
                spuInfoEntity.setPublishStatus(1);
                this.baseMapper.update(spuInfoEntity,qw);
            }else {
                //TODO 远程调用失败 重试？接口幂等性 重复调用？
            }


        }
        return null;
    }
}
